import tkinter as tk
from tkinter import ttk, messagebox, font, filedialog
import requests
import json
import re
import time

class TranslatorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("中文-维吾尔语翻译器")
        self.root.geometry("1200x800")
        
        # API配置
        self.TOKEN_URL = 'https://open.xjguoyu.cn/api/auth/oauth/token'
        self.MT_API_URL = 'https://open.xjguoyu.cn/api/core/1.0/mt'
        self.CLIENT_ID = '6d9ed85e9826e6de8b6a39cea81bba86'
        self.CLIENT_SECRET = 'xYXYcMmBeTDRGa6HQwPpRCieTfzbKcDZ'
        self.APP_KEY = 'ldxlVOlPTkF5qyKKNZxkkiBgu2qkFh47'
        self.MAX_CHARS = 300
        
        # 创建维吾尔语字体
        self.uyghur_font = font.Font(family="Uyghur Ekran", size=14)
        
        # 设置主题样式
        style = ttk.Style()
        style.configure('TButton', padding=5)
        style.configure('TLabelframe', padding=10)
        style.configure('TFrame', padding=5)
        
        self.create_widgets()
        self.access_token = None
        self.get_access_token()

    def split_text_into_segments(self, text):
        """将文本分割成段落和句子"""
        # 首先按段落分割
        paragraphs = text.split('\n')
        segments = []
        
        for paragraph in paragraphs:
            if not paragraph.strip():
                continue
                
            # 按句子分割每个段落
            sentences = re.split('([。！？!?])', paragraph)
            current_segment = ""
            
            for i in range(0, len(sentences), 2):
                sentence = sentences[i].strip()
                punctuation = sentences[i+1] if i+1 < len(sentences) else ""
                
                if not sentence:
                    continue
                    
                # 如果当前句子会导致段落超过字符限制，保存当前段落并开始新段落
                if len(current_segment + sentence + punctuation) > self.MAX_CHARS:
                    if current_segment:
                        segments.append(current_segment)
                    current_segment = sentence + punctuation
                else:
                    current_segment += sentence + punctuation
            
            # 添加最后一个段落
            if current_segment:
                segments.append(current_segment)
                
        return segments

    def translate_segment(self, text):
        """翻译单个文本段落"""
        self.log(f"\n正在翻译文本: {text}")
        
        # 如果token无效，尝试重新获取
        if not self.access_token:
            self.get_access_token()
        
        headers = {
            'Content-Type': 'application/json;charset=utf-8',
            'Authorization': f'Bearer {self.access_token}'
        }

        params = {
            'appKey': self.APP_KEY
        }

        data = {
            'text': text,
            'src': 'cn',
            'to': 'ug'
        }

        try:
            response = requests.post(
                self.MT_API_URL,
                params=params,
                headers=headers,
                json=data
            )
            
            self.log(f"翻译请求状态码: {response.status_code}")
            self.log(f"翻译响应内容: {response.text}")
            
            if response.status_code == 401:  # token过期
                self.log("Token已过期，尝试重新获取")
                self.get_access_token()
                # 用新token重试
                headers['Authorization'] = f'Bearer {self.access_token}'
                response = requests.post(
                    self.MT_API_URL,
                    params=params,
                    headers=headers,
                    json=data
                )
            
            result = response.json()
            
            if response.status_code == 200:
                if 'value' in result:
                    translated_text = result['value']
                    self.log(f"获取到翻译结果: {translated_text}")
                    if translated_text:
                        return translated_text
                self.log(f"API返回数据结构: {result}")
                raise Exception("未能从API响应中获取翻译结果")
            else:
                error_msg = result.get('message', '翻译失败')
                self.log(f"翻译失败: {error_msg}")
                raise Exception(error_msg)
                
        except Exception as e:
            self.log(f"翻译异常: {str(e)}")
            raise

    def translate(self):
        """执行翻译"""
        text = self.input_text.get("1.0", tk.END).strip()
        if not text:
            messagebox.showwarning("警告", "请输入要翻译的文本")
            return

        self.log_text.delete("1.0", tk.END)
        self.output_text.delete("1.0", tk.END)
        
        try:
            # 分割文本
            segments = self.split_text_into_segments(text)
            total_segments = len(segments)
            self.log(f"文本已分割为 {total_segments} 个部分")
            
            # 设置进度条
            self.progress_bar['maximum'] = total_segments
            self.progress_bar['value'] = 0
            
            translated_segments = []
            for i, segment in enumerate(segments, 1):
                self.progress_var.set(f"正在翻译第 {i}/{total_segments} 段")
                self.progress_bar['value'] = i
                self.log(f"\n翻译第 {i} 段: {segment}")
                
                try:
                    result = self.translate_segment(segment)
                    if result:
                        translated_segments.append(result)
                        self.update_output("\n\n".join(translated_segments))
                        self.root.update()
                except Exception as e:
                    self.log(f"翻译第 {i} 段时出错: {str(e)}")
                    continue
                
                time.sleep(1)  # 避免请求过快
            
            if translated_segments:
                self.progress_var.set("翻译完成")
                self.progress_bar['value'] = total_segments
            else:
                self.progress_var.set("翻译失败")
                self.progress_bar['value'] = 0
                raise Exception("没有成功翻译任何内容")
            
        except Exception as e:
            self.progress_var.set("翻译失败")
            self.progress_bar['value'] = 0
            messagebox.showerror("错误", f"翻译失败: {str(e)}")

    def update_output(self, text):
        """更新输出框内容，确保从右到左显示并保持段落格式"""
        self.output_text.delete("1.0", tk.END)
        if not text:
            return
        
        self.log(f"更新输出内容: {text}")
        
        paragraphs = text.split('\n\n')
        for i, paragraph in enumerate(paragraphs):
            if i > 0:
                self.output_text.insert(tk.END, '\n\n')
            if paragraph.strip():
                # 在每个段落前添加特殊字符来强制从右到左显示
                self.output_text.insert(tk.END, '\u200F' + paragraph.strip(), 'rtl')
        
        # 确保滚动到最新内容
        self.output_text.see(tk.END)
        self.root.update()

    def create_widgets(self):
        """创建GUI组件"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 创建API配置区域
        api_frame = ttk.LabelFrame(main_frame, text="API配置", padding="5")
        api_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=5)
        
        # Client ID
        ttk.Label(api_frame, text="Client ID:").grid(row=0, column=0, padx=5, pady=2)
        self.client_id_var = tk.StringVar(value=self.CLIENT_ID)
        self.client_id_entry = ttk.Entry(api_frame, textvariable=self.client_id_var, width=40)
        self.client_id_entry.grid(row=0, column=1, padx=5, pady=2)
        
        # Secret
        ttk.Label(api_frame, text="Secret:").grid(row=1, column=0, padx=5, pady=2)
        self.secret_var = tk.StringVar(value=self.CLIENT_SECRET)
        self.secret_entry = ttk.Entry(api_frame, textvariable=self.secret_var, width=40)
        self.secret_entry.grid(row=1, column=1, padx=5, pady=2)
        
        # APP Key
        ttk.Label(api_frame, text="APP Key:").grid(row=2, column=0, padx=5, pady=2)
        self.app_key_var = tk.StringVar(value=self.APP_KEY)
        self.app_key_entry = ttk.Entry(api_frame, textvariable=self.app_key_var, width=40)
        self.app_key_entry.grid(row=2, column=1, padx=5, pady=2)
        
        # 保存API配置按钮
        save_api_button = ttk.Button(api_frame, text="保存API配置", command=self.save_api_config)
        save_api_button.grid(row=3, column=0, columnspan=2, pady=5)
        
        # 创建上部框架（输入输出区域）
        top_frame = ttk.Frame(main_frame)
        top_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 创建输入区域
        input_frame = ttk.LabelFrame(top_frame, text="输入中文", padding="5")
        input_frame.grid(row=0, column=0, padx=5, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        self.input_text = tk.Text(input_frame, height=15, width=50, wrap=tk.WORD)
        self.input_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        input_scroll = ttk.Scrollbar(input_frame, orient=tk.VERTICAL, command=self.input_text.yview)
        input_scroll.grid(row=0, column=1, sticky=(tk.N, tk.S))
        self.input_text['yscrollcommand'] = input_scroll.set
        
        # 创建输出区域
        output_frame = ttk.LabelFrame(top_frame, text="维吾尔语译文", padding="5")
        output_frame.grid(row=0, column=1, padx=5, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        self.output_text = tk.Text(output_frame, height=15, width=50, wrap=tk.WORD, font=self.uyghur_font)
        self.output_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        self.output_text.tag_configure('rtl', justify='right')
        
        output_scroll = ttk.Scrollbar(output_frame, orient=tk.VERTICAL, command=self.output_text.yview)
        output_scroll.grid(row=0, column=1, sticky=(tk.N, tk.S))
        self.output_text['yscrollcommand'] = output_scroll.set
        
        # 修改按钮区域
        self.button_frame = ttk.Frame(main_frame, padding="5")
        self.button_frame.grid(row=2, column=0, sticky=(tk.W, tk.E))
        
        translate_button = ttk.Button(self.button_frame, text="翻译", command=self.translate, width=15)
        translate_button.grid(row=0, column=0, padx=5)
        
        import_word_button = ttk.Button(self.button_frame, text="导入Word", command=self.import_word, width=15)
        import_word_button.grid(row=0, column=1, padx=5)
        
        copy_button = ttk.Button(self.button_frame, text="复制翻译结果", command=self.copy_result, width=15)
        copy_button.grid(row=0, column=2, padx=5)
        
        export_button = ttk.Button(self.button_frame, text="导出到Word", command=self.export_to_word, width=15)
        export_button.grid(row=0, column=3, padx=5)
        
        # 创建进度条区域
        progress_frame = ttk.Frame(main_frame)
        progress_frame.grid(row=3, column=0, sticky=(tk.W, tk.E), pady=5)
        
        self.progress_var = tk.StringVar(value="就绪")
        progress_label = ttk.Label(progress_frame, textvariable=self.progress_var)
        progress_label.grid(row=0, column=0, padx=5)
        
        self.progress_bar = ttk.Progressbar(progress_frame, mode='determinate', length=300)
        self.progress_bar.grid(row=0, column=1, padx=5, sticky=(tk.W, tk.E))
        
        # 创建日志区域
        log_frame = ttk.LabelFrame(main_frame, text="日志", padding="5")
        log_frame.grid(row=4, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
        
        self.log_text = tk.Text(log_frame, height=8, width=100, wrap=tk.WORD)
        self.log_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        log_scroll = ttk.Scrollbar(log_frame, orient=tk.VERTICAL, command=self.log_text.yview)
        log_scroll.grid(row=0, column=1, sticky=(tk.N, tk.S))
        self.log_text['yscrollcommand'] = log_scroll.set
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        
        main_frame.columnconfigure(0, weight=1)
        main_frame.rowconfigure(0, weight=1)
        main_frame.rowconfigure(3, weight=1)
        
        top_frame.columnconfigure(0, weight=1)
        top_frame.columnconfigure(1, weight=1)
        top_frame.rowconfigure(0, weight=1)
        
        input_frame.columnconfigure(0, weight=1)
        input_frame.rowconfigure(0, weight=1)
        
        output_frame.columnconfigure(0, weight=1)
        output_frame.rowconfigure(0, weight=1)
        
        progress_frame.columnconfigure(1, weight=1)
        
        log_frame.columnconfigure(0, weight=1)
        log_frame.rowconfigure(0, weight=1)

    def log(self, message):
        """添加日志消息"""
        self.log_text.insert(tk.END, message + "\n")
        self.log_text.see(tk.END)
        self.root.update()

    def get_access_token(self):
        """获取访问令牌"""
        try:
            params = {
                'grant_type': 'client_credentials',
                'client_id': self.CLIENT_ID,
                'secret': self.CLIENT_SECRET
            }
            
            self.log(f"发送Token请求，参数: {params}")
            
            response = requests.get(
                self.TOKEN_URL,
                params=params
            )
            
            self.log(f"Token请求状态码: {response.status_code}")
            self.log(f"Token响应内容: {response.text}")
            
            result = response.json()
            
            if response.status_code == 200 and 'access_token' in result:
                self.access_token = result['access_token']
                self.log("成功获取访问令牌")
            else:
                error_msg = result.get('message', '获取访问令牌失败')
                self.log(f"获取牌失败: {error_msg}")
                raise Exception(error_msg)
            
        except Exception as e:
            self.log(f"获取访问令牌失败: {str(e)}")
            messagebox.showerror("错误", f"获取访问令牌失败: {str(e)}")

    def copy_result(self):
        """复制翻译结果到剪贴板"""
        result = self.output_text.get("1.0", tk.END).strip()
        if result:
            self.root.clipboard_clear()
            self.root.clipboard_append(result)
            messagebox.showinfo("提示", "翻译结果已复制到剪贴板")
        else:
            messagebox.showwarning("警告", "没有可复制的翻译结果")

    def export_to_word(self):
        """导出翻译结果到Word文档"""
        try:
            from docx import Document
            from docx.shared import Pt, RightTabStop
            from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
            from docx.oxml.ns import qn
            
            result = self.output_text.get("1.0", tk.END).strip()
            if not result:
                messagebox.showwarning("警告", "没有可导出的翻译结果")
                return
            
            # 创建保存文件对话框
            file_path = filedialog.asksaveasfilename(
                defaultextension=".docx",
                filetypes=[("Word文档", "*.docx")],
                title="保存翻译结果"
            )
            
            if not file_path:
                return
            
            # 创建Word文档
            doc = Document()
            
            # 设置文档方向为从右到左
            section = doc.sections[0]
            section.page_width, section.page_height = section.page_height, section.page_width
            
            # 设置默认字体
            style = doc.styles['Normal']
            style.font.name = 'Microsoft Uighur'
            style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Microsoft Uighur')
            style.font.size = Pt(12)
            
            # 添加内容
            paragraphs = result.split('\n\n')
            for para in paragraphs:
                if para.strip():
                    p = doc.add_paragraph(para.strip())
                    p.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
                    p.style = style
                    # 设置段落方向为从右到左
                    p._element.get_or_add_pPr().set(qn('w:bidi'), '1')
            
            # 保存文档
            doc.save(file_path)
            messagebox.showinfo("成功", "翻译结果已成功导出到Word文档")
            
        except Exception as e:
            messagebox.showerror("错误", f"导出失败: {str(e)}")

    def save_api_config(self):
        """保存API配置"""
        self.CLIENT_ID = self.client_id_var.get()
        self.CLIENT_SECRET = self.secret_var.get()
        self.APP_KEY = self.app_key_var.get()
        
        # 重新获取token
        self.access_token = None
        self.get_access_token()
        
        messagebox.showinfo("成功", "API配置已更新")

    def import_word(self):
        """导入Word文档并直接翻译"""
        try:
            from docx import Document
            import win32com.client
            from docx.shared import Pt
            from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
            from docx.oxml.ns import qn
            
            # 选择Word文件
            file_path = filedialog.askopenfilename(
                filetypes=[("Word文档", "*.docx;*.doc")],
                title="选择要翻译的Word文档"
            )
            
            if not file_path:
                return
            
            # 如果是.doc文件，先转换为.docx
            if file_path.endswith('.doc'):
                word = win32com.client.Dispatch('Word.Application')
                doc = word.Documents.Open(file_path)
                docx_path = file_path + 'x'
                doc.SaveAs2(docx_path, FileFormat=16)
                doc.Close()
                word.Quit()
                file_path = docx_path
            
            # 读取Word文档
            doc = Document(file_path)
            
            # 创建保存翻译结果的文件路径
            save_path = filedialog.asksaveasfilename(
                defaultextension=".docx",
                filetypes=[("Word文档", "*.docx")],
                title="选择保存翻译结果的位置"
            )
            
            if not save_path:
                return
            
            # 设置进度条最大值（段落数 + 表格单元格数）
            total_items = len(doc.paragraphs)
            for table in doc.tables:
                total_items += sum(len(row.cells) for row in table.rows)
            
            self.progress_bar['maximum'] = total_items
            self.progress_bar['value'] = 0
            current_item = 0
            
            # 设置文档默认样式
            style = doc.styles['Normal']
            style.font.name = 'Microsoft Uighur'
            style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Microsoft Uighur')
            style.font.size = Pt(12)
            
            # 翻译段落
            for para in doc.paragraphs:
                if para.text.strip():
                    self.progress_var.set(f"正在翻译段落 {current_item + 1}/{total_items}")
                    try:
                        translated_text = self.translate_segment(para.text)
                        if translated_text:
                            para.text = translated_text
                            para.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
                            para.style = style
                            # 设置段落方向为从右到左
                            para._element.get_or_add_pPr().set(qn('w:bidi'), '1')
                    except Exception as e:
                        self.log(f"翻译段落失败: {str(e)}")
                    
                    current_item += 1
                    self.progress_bar['value'] = current_item
                    self.root.update()
            
            # 翻译表格
            for table in doc.tables:
                for row in table.rows:
                    for cell in row.cells:
                        if cell.text.strip():
                            self.progress_var.set(f"正在翻译表格单元格 {current_item + 1}/{total_items}")
                            try:
                                translated_text = self.translate_segment(cell.text)
                                if translated_text:
                                    # 清空单元格内容
                                    for paragraph in cell.paragraphs:
                                        paragraph._element.getparent().remove(paragraph._element)
                                    
                                    # 添加新段落
                                    paragraph = cell.add_paragraph()
                                    paragraph.text = translated_text
                                    paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
                                    paragraph.style = style
                                    # 设置段落方向为从右到左
                                    paragraph._element.get_or_add_pPr().set(qn('w:bidi'), '1')
                            except Exception as e:
                                self.log(f"翻译表格单元格失败: {str(e)}")
                            
                            current_item += 1
                            self.progress_bar['value'] = current_item
                            self.root.update()
            
            # 保存翻译后的文档
            doc.save(save_path)
            
            self.progress_var.set("翻译完成")
            self.progress_bar['value'] = total_items
            messagebox.showinfo("成功", "Word文档翻译完成！")
            
        except Exception as e:
            self.progress_var.set("翻译失败")
            self.progress_bar['value'] = 0
            messagebox.showerror("错误", f"处理Word文档失败: {str(e)}")

def main():
    root = tk.Tk()
    app = TranslatorApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()